using System;
using System.IO;

using Atomic.Interfaces.Yphon;
using Atomic.Libraries;
using Atomic.Libraries.Compression;
using Atomic.Structures;

namespace Atomic.Vasp.LinearResponse
{
	[Serializable]
	public class SimpleVaspLinearResponseResult : SimpleVaspResult, IVaspLinearResponseResult, IYphonVaspLinearResponseResult
	{
		private CompressedData contcar, outcar;

		public SimpleVaspLinearResponseResult(DirectoryInfo directory)
			: base(directory)
		{
			// Still keep the original OUTCAR, as it's used for phonons.
			ReadFile(directory, "CONTCAR", true, out contcar);
			ReadFile(directory, "OUTCAR", true, out outcar);
		}

		private static void ReadFile(DirectoryInfo directory, string fileName, bool required, out CompressedData data)
		{
			if (directory.AddFile(fileName).AddFileExtension(".ignore").Exists && !required)
			{
				// Ignore this file.
				data = null;
				return;
			}

			if (directory.AddFile(fileName).Exists && directory.AddFile(fileName).Length > 0)
			{
				data = CompressedData.Read(directory.AddFile(fileName));
				return;
			}

			if (directory.AddFile(fileName).AddFileExtension(".bz2").Exists && directory.AddFile(fileName).AddFileExtension(".bz2").Length > 0)
			{
				data = CompressedData.ReadCompressed(directory.AddFile(fileName).AddFileExtension(".bz2"));
				return;
			}

			if (required)
			{
				throw new FileNotFoundException("Couldn't find VASP output file.", directory.AddFile(fileName).FullName);
			}

			data = null;
		}

		public void Compress()
		{
			foreach (CompressedData data in new CompressedData[] { contcar, outcar })
			{
				if (data != null)
				{
					data.Compress();
				}
			}
		}

		public IBinaryData Contcar
		{
			get
			{
				return contcar;
			}
		}

		public IBinaryData Outcar
		{
			get
			{
				return outcar;
			}
		}

		public SiteMatrix ForceConstants
		{
			get
			{
				throw new NotImplementedException();
			}
		}
	}
}
